 grammar tsl_MR;


 tsl:parametersStatement environmentStatement outputStatement mrStat? EOF;
 parametersStatement:'parameters' COLON paragraphStatement+;
 environmentStatement:'environments' COLON paragraphStatement+;
 outputStatement:'output' COLON outparagraphStatement+;
 colon:COLON;
 paragraphStatement:NAME COLON lineStatement+;
 outparagraphStatement:NAME COLON lineStatement+;
 lineStatement:variant constraint*;
 variant:dataTypes compare | dataTypes NAME '[' (compare ','?)+ ']';
 dataTypes:'string'|'int'|'double'|'boolean'|'decimal' |'float' | 'duration' |'dateTime' | 'date' | 'time' | 'gYearMonth'
                 |'gYear' |'gMonthDay' |'gDay'| 'gMonth'| 'hexBinary' | 'base64Binary' | 'anyURI' | 'QName'| 'NOTATION'
                 |'Z'|'R'|'N'|'R+';
 compare:NAME ( ('not')? comparisonOperator expression )?;
 comparisonOperator:'='|'>'|'<'|'(-'|'>='|'<='|'=='|'subset' ;
 expression:(NUMBER|NAME|'Z'|'N'|'R'|'Z+') (exp (NUMBER|NAME|'Z'|'N'|'R'|'R+'))*
            |'sin' '(' NAME ')' |'min' '(' (NAME ','?)+ ')'|'max' '(' (NAME ','?)+ ')';
 exp:'+'|'-'|'*'|'/'|'%'|'<<'|'>>';
 constraint:ifStatement|propertyStatement|errorStatement|singleStatement;
 ifStatement: '[' 'if' NAME ']';
 propertyStatement:'[' 'property' NAME ']';
 errorStatement:'[' 'error'  ']';
 singleStatement:'[' 'single' ']';
 mrStat:spec iteNumbers? iteSuite? iteRate? mrStatement+;
 spec:'MR_spec' COLON '{' (NAME (',')?)+ '}';
 iteNumbers:'iteNumbers' COLON NUMBER;
 iteSuite:'iteSuite' COLON NUMBER;
 iteRate:'iteRate' COLON NUMBER;
 mrStatement:'MR'  NAME colon mr;
 mr:input output relation;
 input:in inFollow;
 output:out outFollow;
 in:'input' colon '[' (NAME ','?)+ ']';
 inFollow:'follow-input' colon '[' (compare ','?)+ ']';
 out:'output' colon '[' (NAME ','?)+ ']';
 outFollow:'follow-output' colon '[' (compare ','?)+ ']';
 relation:'relation' colon ((compare ('or'|'and')?)+ ';')+ ;
 encoding_decl: NAME ;//记录NAME值，方便编译
/*****************************************************************************
 *                               Lexer rules
 *****************************************************************************/


// Keywords
ELSE               : 'else' ;
THEN               : 'then' ;
LET                : 'let' ;
DOM                : 'dom' ;
RAN                : 'ran' ;
MIN                : 'min' ;
MAX                : 'max' ;
//数据结构分开讨论
//
NUMBER
    :   '0' ([xX] [0-9a-fA-F]+         ([lL]  | [eE] [+-]? [0-9]+)?
    |        [oO] [0-7]+                [lL]?
    |        [bB] [01]+                 [lL]?)
    | '-'? ([0-9]+ '.' [0-9]* | '.' [0-9]+)         ([eE] [+-]? [0-9]+)?       [jJ]?
    | '-'? [0-9]+                          ([lL]  | [eE] [+-]? [0-9]+ [jJ]? | [jJ])?
    ;

COMMENT: '#' ~[\r\n]* -> skip;

COLON: ':' ;

NAME: [a-zA-Z_] [a-zA-Z0-9_]* ;


WHITESPACE: ('\t' | ' ')+
{
}  -> channel(HIDDEN)
    ;

NEWLINE:('\r'? '\n' | '\r')+
{
}  -> channel(HIDDEN)
     ;

STRING
        : ([uUbB]? [rR]? | [rR]? [uUbB]?)
        ( '\''     ('\\' (([ \t]+ ('\r'? '\n')?)|.) | ~[\\\r\n'])*  '\''
        | '"'      ('\\' (([ \t]+ ('\r'? '\n')?)|.) | ~[\\\r\n"])*  '"'
        | '"""'    ('\\' .                          | ~'\\'     )*? '"""'
        | '\'\'\'' ('\\' .                          | ~'\\'     )*? '\'\'\''
        )
        ;



UNKNOWN: . -> skip;